package es.kivitel.android.sms.kernel;


import java.lang.reflect.Field;
import java.util.Calendar;
import java.util.HashMap;

import android.content.Context;
import android.database.Cursor;
import android.database.CursorIndexOutOfBoundsException;
import android.util.Log;

public abstract class Event {
	
	private int mode;
	protected long sendingdate;
	protected String subject;
	private String comment;
	protected String destination;
	protected String content;
	private int sent;
	private long id;
	public static final int FOREGROUND_MODE = 0;
	public static final int BACKGROUND_MODE = 1;
	protected static final int TIME_EXPIRED = 2;
	protected static final int SMS_EVENT = 0;
	protected static final int EMAIL_EVENT = 1;
	protected static final int MMS_EVENT = 2;	
	private static final int EVENT_TABLE = 0;
	private static final String PREFFIX = "EVT_";
	private static final Object EVENT_PK = "EVT_ID";
	private static final String TAG = Event.class.getName();
	public static final int EVENT_SENT = 1;
	public static final int EVENT_NOT_SENT = 0;
	private int type;
	
	public abstract boolean send(Context ctx);
	
	public void setDestination(String destination) {
		this.destination = destination;
	}
	public String getDestination() {
		return destination;
	}
	public void setSendingDate(Calendar calendar){
		this.sendingdate = (long) calendar.getTimeInMillis();
	}
	public void setSendingDate(long sendingDate) {
		this.sendingdate = sendingDate;
	}
	public long getSendingDate() {
		return sendingdate;
	}
	
	public void setContent(String content) {
		this.content = content;
	}
	public String getContent() {
		return content;
	}
	public void setType(int type) {
		this.type = type;
	}

	public int getType() {
		return type;
	}

	public void setSubject(String subject) {
		this.subject = subject;
	}

	public String getSubject() {
		return subject;
	}
	public static Event extractEvent(Cursor c) throws IllegalArgumentException, SecurityException, IllegalAccessException, NoSuchFieldException{
		Event e;
		if(c.isClosed()){
			throw new CursorIndexOutOfBoundsException("Unable to extract event from Event.extractEvent(Cursor c); the cursor is closed");
		}
		HashMap<String,Integer> position= 
		DatabaseManager.structure.get(DatabaseManager.tables.get(EVENT_TABLE));
		if(c.getInt(position.get("EVT_TYPE"))==Event.SMS_EVENT)
			e = new SmsEvent();
		else //EMAIL_EVENT
			e = new EmailEvent();
		//For each column, we'll extract its content to the proper property
		for(String key : position.keySet()){
			Log.i(TAG,key+","+key.replaceFirst(PREFFIX, "").toLowerCase());
			switch(position.get(key)){
				case DatabaseManager.INTEGER:
					if(!Event.class.getDeclaredField(key.replace(Event.PREFFIX, "").toLowerCase()).getGenericType().equals(int.class))
						Event.class.getDeclaredField(key.replace(Event.PREFFIX, "").toLowerCase()).set(e,c.getLong(c.getColumnIndex(key)));
					else
						Event.class.getDeclaredField(key.replace(Event.PREFFIX, "").toLowerCase()).set(e,c.getInt(c.getColumnIndex(key)));
					break;
				case DatabaseManager.TEXT:						
					if(c.getString(c.getColumnIndex(key))!=null)
						Event.class.getDeclaredField(key.replace(Event.PREFFIX, "").toLowerCase()).set(e,c.getString(c.getColumnIndex(key)));
					break;
				case DatabaseManager.REAL:
					Event.class.getDeclaredField(key.replace(Event.PREFFIX, "").toLowerCase()).set(e,c.getDouble(c.getColumnIndex(key)));
					break;
				default:
					throw new NullPointerException("Unable to store event, unrecognizable type");
			}			
		}
		return e;
	}
	public boolean store(Context ctx) throws Exception{
		DatabaseManager.initialize(ctx);
		String query = "INSERT INTO "+DatabaseManager.tables.get(EVENT_TABLE)+" (";
		HashMap<String,Integer> position= 
			DatabaseManager.structure.get(DatabaseManager.tables.get(EVENT_TABLE));
		for(String key : position.keySet()){
			if(!key.equals(Event.EVENT_PK)){
				query+=key+",";
			}
		}
		query=query.substring(0,query.length()-1);
		query+=") VALUES (";
		Field[] fields = Event.class.getDeclaredFields();
		for(String key : position.keySet()){
			if(!key.equals(Event.EVENT_PK)){
				switch(position.get(key)){
					case DatabaseManager.INTEGER:
						query+=Event.class.getDeclaredField(key.replace(Event.PREFFIX, "").toLowerCase()).getLong(this)+",";
						break;
					case DatabaseManager.TEXT:						
						if(Event.class.getDeclaredField(key.replace(Event.PREFFIX, "").toLowerCase()).get(this)!=null)
							query+="\""+(String)Event.class.getDeclaredField(key.replace(Event.PREFFIX, "").toLowerCase()).get(this)+"\",";
						else
							query+="NULL,";
						break;
					case DatabaseManager.REAL:
						query+=Event.class.getDeclaredField(key.replace(Event.PREFFIX, "").toLowerCase()).getDouble(this)+",";
						break;
					default:
						throw new NullPointerException("Unable to store event, unrecognizable type");
				}
			}
		}
		query=query.substring(0,query.length()-1);
		query+=")";
		return DatabaseManager.execute(query);

		
	}

	public void setSent(boolean sent) {
		if(sent)
			this.sent = 1;
		else
			this.sent = 0;			
	}

	public boolean getSent() {
		if(sent==1)
			return true;
		return false;
	}

	public void setMode(int mode) {
		this.mode = mode;
	}

	public int getMode() {
		return mode;
	}

	public void setComment(String comment) {
		this.comment = comment;
	}

	public String getComment() {
		return comment;
	}
}
